#ifndef _TYPEC_PD_TIMER_H_
#define _TYPEC_PD_TIMER_H_

#include "typec_pd_config.h"

enum typec_pd_timer {
    TYPEC_PD_TIMER_NONE = 0,

    TYPEC_TIMER_START = 1,
    TYPEC_TIMER_CC_DEBOUNCE = TYPEC_TIMER_START,
    TYPEC_TIMER_PD_DEBOUNCE,
    TYPEC_TIMER_TRYCC_DEBOUNCE,
    TYPEC_TIMER_ERROR_RECOVERY,
    TYPEC_TIMER_SRC_DISCONNECT,
    TYPEC_TIMER_DRP_TRY,
    TYPEC_TIMER_DRP_TRYWAIT,
    TYPEC_TIMER_TRY_TIMEOUT,
    TYPEC_TIMER_DRP_TRANSITION,
    TYPEC_TIMER_END,

    PD_TIMER_START = TYPEC_TIMER_END,
    PD_TIMER_PE_STARTUP = PD_TIMER_START,
    PD_TIMER_SENDER_RESPONSE,
    PD_TIMER_SOURCECAPABILITY,
    PD_TIMER_SINKWAITCAP,
    PD_TIMER_PSTRANSITION,
    PD_TIMER_PSSOURCEOFF,
    PD_TIMER_PSSOURCEON,
    PD_TIMER_NORESPONSE,
    PD_TIMER_BISTCONTMODE,
    PD_TIMER_SWAPSOURCESTART,
    PD_TIMER_PSHARDRESET,
    PD_TIMER_VDMRESPONSE,
    PD_TIMER_DISCOVERIDENTITY,
    PD_TIMER_SINKTX,
    PD_TIMER_CHUNKINGNOTSUPPORTED,
    PD_TIMER_SINKPPSPERIODIC,

    PD_TIMER_SRCRECOVER,
    PD_TIMER_SRCTRANSITION,
    PD_TIMER_SRCTRANSREQ,
    PD_TIMER_VCONNSOURCEON,
    PD_TIMER_VCONNON,
    PD_TIMER_DELAY_START_DPM,

    PD_TIMER_END,

    TYPEC_PD_TIMER_MAX = PD_TIMER_END,
};

#define TYPEC_TIMER_T_CC_DEBOUNCE           150
#define TYPEC_TIMER_T_PD_DEBOUNCE           15
#define TYPEC_TIMER_T_TRYCC_DEBOUNCE        15
#define TYPEC_TIMER_T_ERROR_RECOVERY        240
#define TYPEC_TIMER_T_SRC_DISCONNECT        5
#define TYPEC_TIMER_T_DRP_TRY               120
#define TYPEC_TIMER_T_DRP_TRYWAIT           600
#define TYPEC_TIMER_T_TRY_TIMEOUT           800
#define TYPEC_TIMER_T_DRP_TRANSITION        40

#define PD_TIMER_T_PE_STARTUP               20
#define PD_TIMER_T_SENDER_RESPONSE          28  // [27, 33], reserve time for firmware and printf
#define PD_TIMER_T_SOURCECAPABILITY         150
#define PD_TIMER_T_SINKWAITCAP              465
#define PD_TIMER_T_PSTRANSITION             500
#define PD_TIMER_T_PSSOURCEOFF              835
#define PD_TIMER_T_PSSOURCEON               435
#define PD_TIMER_T_NORESPONSE               5000
#define PD_TIMER_T_BISTCONTMODE             45
#define PD_TIMER_T_SWAPSOURCESTART          20
#define PD_TIMER_T_PSHARDRESET              30
#define PD_TIMER_T_VDMRESPONSE              28  // [27, 33]
#define PD_TIMER_T_DISCOVERIDENTITY         40  // [40, 50]
#define PD_TIMER_T_SINKTX                   18  // [16, 20]
#define PD_TIMER_T_CHUNKINGNOTSUPPORTED     40  // [40, 50]
#define PD_TIMER_T_SINKPPSPERIODIC          8000  // [ , 10s]

#define PD_TIMER_T_SRCRECOVER               800  // [660, 1000]
#define PD_TIMER_T_SRCTRANSITION            30
#define PD_TIMER_T_SRCTRANSREQ              50  // [ , 325]
#define PD_TIMER_T_VCONNSOURCEON            20  // [ , 50]
#define PD_TIMER_T_VCONNON                  150
#define PD_TIMER_T_DELAY_START_DPM          40  // must >= DiscoverIdentityTimer and SinkTxTimer

struct typec_timer_info {
    bool valid;
    uint8_t timer;
    uint32_t expiry;
};

struct pd_timer_info {
    bool valid;
    bool permanent;
    uint8_t timer;
    uint32_t expiry;
};

void typec_pd_timer_init(void);
void typec_timer_enable(uint8_t timer, uint32_t timer_value);
void typec_timer_disable(uint8_t timer);
void typec_timer_disable_all(void);
void pd_timer_enable(uint8_t timer, uint32_t timer_value, bool permanent);
void pd_timer_disable(uint8_t pd_timer);
void pd_timer_disable_all(void);
void pd_timer_disable_all_not_permanent(void);
uint8_t typec_expired_timer(void);
uint8_t pd_expired_timer(void);
#endif
